package cn.jinjimi.app.modules.Resource;

import android.webkit.WebResourceResponse;

import cn.jinjimi.base.util.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Roy
 * Date: 2017/3/3
 */

public class NetResourceManager {
    private static volatile NetResourceManager instance = null;
    private ResourceProvider mResourceProvider;

    /* 双重检验锁的懒汉模式的单例模式*/
    public static NetResourceManager getInstance() {
        if (instance == null) {
            synchronized (NetResourceManager.class) {
                if (instance == null)
                    instance = new NetResourceManager();
            }
        }
        return instance;
    }

    private NetResourceManager() {
        mResourceProvider = new ResourceProvider();
    }

    /* 检查是否需要更新离线资源包 */
    public void checkResource() {
        final Resource.Config config = Resource.getInstance().getConfig();
        if (config != null) {
            Resource.Bundle main = buildPublicBundle(config);
            mResourceProvider.setMainBundle(main);
        } else {
            mResourceProvider.setMainBundle(null);
        }
    }


    public void checkBundles() {
        List<Resource.Bundle> bundle = Resource.getInstance().getBundle();
        List<Resource.Bundle> mValidBundles = new ArrayList<>();
        if (bundle != null && !bundle.isEmpty()) {
            for (Resource.Bundle b : bundle) {
                if (b.isValid()) {
                    mValidBundles.add(b);
                }
            }
        }
        mResourceProvider.setExtBundles(mValidBundles);
    }

    private Resource.Bundle buildPublicBundle(Resource.Config config) {
        Resource.Bundle bundle = new Resource.Bundle();
        bundle.entranceUrl = "/";
        bundle.id = config.id;
        bundle.md5 = config.md5;
        bundle.link = config.link;
        bundle.notifyUrl = config.notifyUrl;
        return bundle.isValid() ? bundle : null;
    }


    /**
     * 切换url时切换bundle资源
     *
     * @param url
     */
    public void onPageStart(String url) {
        if (mResourceProvider != null) {
            url = parseUrl(url);
            mResourceProvider.onChangeCurrentBundle(url);
        }
    }

    /**
     * 判断是否含有此url的资源
     *
     * @param url
     * @return
     */
    public boolean containResource(String url) {
        url = parseUrl(url);
        return mResourceProvider != null && mResourceProvider.containResource(url);
    }

    private String parseUrl(String url) {
        String parseUrl = url;
        if (url.contains("?")) {
            parseUrl = parseUrl.substring(0, url.indexOf("?"));
            if (parseUrl.contains("#")) {
                parseUrl = parseUrl.substring(0, parseUrl.indexOf("#"));
            }
        }
        return parseUrl;
    }

    /**
     * 根据url返回本地资源
     *
     * @param url
     * @return
     */
    public WebResourceResponse createWebResourceResponse(String url) {
        url = parseUrl(url);
        return mResourceProvider != null ? mResourceProvider.createWebResourceResponse(url) : null;
    }

    private static class ResourceProvider {
        private BundleHelper mainBundleHelper;
        private boolean mainLoaded, extLoaded;
        private List<BundleHelper> mBundleHelpers;

        private BundleHelper mMatchBundleHelper;

        private Set<String> mBundleIds = new HashSet<>();

        public ResourceProvider() {
        }

        private void setMainBundle(Resource.Bundle mainBundle) {
            mainLoaded = true;
            if (mainBundle != null) {
                mBundleIds.add(mainBundle.id);
                this.mainBundleHelper = new BundleHelper(mainBundle);
                mainBundleHelper.init();
            }
            clearFile();

        }

        private void setExtBundles(List<Resource.Bundle> bundles) {
            extLoaded = true;
            if (bundles != null && !bundles.isEmpty()) {
                mBundleHelpers = new ArrayList<>();
                mBundleHelpers.clear();
                for (Resource.Bundle bundle : bundles) {
                    mBundleIds.add(bundle.id);
                    BundleHelper bh = new BundleHelper(bundle);
                    bh.init();
                    mBundleHelpers.add(bh);
                }
            }
            clearFile();
        }

        private void clearFile() {
            if (mainLoaded && extLoaded) {
                BundleHelper.clearUselessFiles(mBundleIds);
            }
        }


        private void onChangeCurrentBundle(String url) {
            if (StringUtils.isEmpty(url)) {
                mMatchBundleHelper = null;
                return;
            }
            if (mBundleHelpers != null && !mBundleHelpers.isEmpty()) {
                for (BundleHelper bh : mBundleHelpers) {
                    if (url.equals(bh.getEntranceUrl())) {
                        mMatchBundleHelper = bh;
                        return;
                    }
                }
            }
        }

        private boolean containResource(String url) {
            return (mMatchBundleHelper != null && mMatchBundleHelper.containResource(url)) ||
                    (mainBundleHelper != null && mainBundleHelper.containResource(url));
        }

        private WebResourceResponse createWebResourceResponse(String url) {
            if (mMatchBundleHelper != null && mMatchBundleHelper.containResource(url)) {
                return mMatchBundleHelper.createWebResourceResponse(url);
            } else if (mainBundleHelper != null && mainBundleHelper.containResource(url)) {
                return mainBundleHelper.createWebResourceResponse(url);
            }
            return null;
        }

    }
}